package com.heima.comment.service.impl;
import java.math.BigDecimal;

import com.heima.comment.service.CommentRepayService;
import com.heima.common.exception.CustomException;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.comment.vo.ApCommentRepayVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @作者 itcast
 * @创建日期 2021/4/23 14:06
 **/
@Service
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    UserFeign userFeign;
    @Override
    public ResponseResult loadCommentRepay(CommentRepayDto dto) {
        // 1. 检查参数  评论id不能为空  评论最小时间  分页
        if(dto.getCommentId() == null){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID,"评论ID不能为空");
        }
        if(dto.getMinDate() == null){
            dto.setMinDate(new Date());
        }
        if(dto.getSize() == null || dto.getSize() < 1){
            dto.setSize(10);
        }
        // 2. 根据评论ID 及  < 回复的最小时间  按照回复时间的降序排序  设置分页
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId())
                                        .and("createdTime").lt(dto.getMinDate()))
                                        .with(Sort.by(Sort.Direction.DESC,"createdTime"))
                                        .limit(dto.getSize());
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        // 3. 判断用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null || apCommentRepays == null || apCommentRepays.size() == 0){
            return ResponseResult.okResult(apCommentRepays);
        }
        // 3.1 判断当前登录用户  对哪些回复点过赞
        List<String> commentRepayIdList = apCommentRepays.stream().map(ApCommentRepay::getId).collect(Collectors.toList());
        // repayId  in  commentRepayIdList    authorId is 登录人id
        Query likeQuery = Query.query(Criteria.where("commentRepayId").in(commentRepayIdList).and("authorId").is(user.getId()));
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(likeQuery, ApCommentRepayLike.class);
        // 如果没有点过赞直接返回
        if(apCommentRepayLikes == null || apCommentRepayLikes.size() == 0){
            return ResponseResult.okResult(apCommentRepays);
        }
        //  点过赞的回复ID集合
        List<String> likedRepayIdList = apCommentRepayLikes.stream().map(ApCommentRepayLike::getCommentRepayId).collect(Collectors.toList());
        List<ApCommentRepayVo> repayVoList = apCommentRepays.stream().map(apCommentRepay -> {
            ApCommentRepayVo apCommentRepayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay, apCommentRepayVo);
            if (likedRepayIdList.contains(apCommentRepayVo.getId())) {
                apCommentRepayVo.setOperation((short) 0);
            }
            return apCommentRepayVo;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(repayVoList);
    }

    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDto dto) {
        //1. 检查参数  评论id  评论内容  必须登录
        if(dto.getCommentId() == null){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID,"评论ID不能为空");
        }
        if(StringUtils.isBlank(dto.getContent()) || dto.getContent().length()>140){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID,"评论内容为空 或者 长度超出限制");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null){
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN,"请先登录");
        }
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if(apComment == null){
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST,"该评论信息不存在");
        }
        //2. 根据登录用户ID查询登录用户信息
        user = userFeign.findUserById(Long.valueOf(user.getId()));
        if(user == null){
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST,"获取登录人信息失败");
        }
        //3. 阿里云文本 对内容检测 TODO
        //4. 保存评论回复内容
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(user.getId());
        apCommentRepay.setAuthorName(user.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentRepay);
        //5. 更新评论回复数量
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult saveCommentRepayLike(CommentRepayLikeDto dto) {
        // 1. 检查参数  评论回复ID  方式 0 1  必须登录
        if(dto.getCommentRepayId() == null||dto.getOperation() == null){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID,"评论ID不能为空");
        }
        if(dto.getOperation() != 0 && dto.getOperation()!=1){
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID,"点赞方式参数错误");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if(user == null){
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN,"请先登录");
        }
        // 2. 根据回复ID 查询回复
        ApCommentRepay commentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        if(commentRepay == null){
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST,"该回复信息不存在");
        }
        Query query = Query.query(
                Criteria.where("commentRepayId").is(dto.getCommentRepayId())
                        .and("authorId").is(user.getId())
        );
        ApCommentRepayLike commentRepayLike = mongoTemplate.findOne(query, ApCommentRepayLike.class);
        if(commentRepayLike != null && dto.getOperation() == 0){
            throw new CustomException(AppHttpCodeEnum.DATA_EXIST,"请勿重复点赞");
        }
        int likes = commentRepay.getLikes();
        // 3. 方式为0
        if(dto.getOperation() == 0){
            //     回复 点赞 +1
            likes = likes+1;
            commentRepay.setLikes(likes);
            mongoTemplate.save(commentRepay);
            //     添加点赞信息
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setAuthorId(user.getId());
            apCommentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            apCommentRepayLike.setOperation((short)0);
            mongoTemplate.save(apCommentRepayLike);
        }else {
            // 4. 取消点赞 为1
            //     回复 点赞 -1
            likes = (likes-1) < 0 ? 0 : (likes - 1);
            commentRepay.setLikes(likes);
            mongoTemplate.save(commentRepay);
            //     删除点赞信息
            mongoTemplate.remove(query,ApCommentRepayLike.class);
        }
        // 5. 返回点赞数量
        Map resultMap = new HashMap<>();
        resultMap.put("likes",likes);
        return ResponseResult.okResult(resultMap);
    }
}
